package com.apache.license.validator;

import com.apache.tools.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.Enumeration;
import java.util.Properties;

/**
 * @author
 */
public class OsUtils {

    public static final boolean IS_MAC = "Mac OS X".equals(System.getProperty("os.name"));

    public static final boolean IS_WINDOWS = System.getProperty("os.name").contains("Windows");

    public static final boolean IS_LINUX = System.getProperty("os.name").toLowerCase()
            .contains("linux");

    private static Logger log = LoggerFactory.getLogger("OS Config");

    private static String linusIp = "eth0,eth1,em1,em2,em3,";

    private static transient String MAC_ADDR = null;

    public static void removeProxySettingsIfMac() {
        // Stupid Safari will only proxy with the
        // OS level Network Proxy settings.
        // We don't want them so nuke them here.
        if (OsUtils.IS_MAC) {
            Properties props = System.getProperties();
            props.remove("http.proxyPort");
            props.remove("http.proxyHost");
            props.remove("https.proxyPort");
            props.remove("https.proxyHost");
        }
    }

    /**
     * 获取本机ip地址
     *
     * @return 返回本机的IP地址
     */
    public static String getLocalIp() {
        String localIp = null;
        try {
            if ("linux".equals(OsUtils.getSystemType())) {
                localIp = getLinuxIP();
            } else {
                localIp = InetAddress.getLocalHost().getHostAddress();
            }
        } catch (Exception e) {
            return "127.0.0.1";
        }
        return localIp;
    }

    /**
     * 获取操作系统类型
     *
     * @return 返回操作系统类型
     */
    public static String getSystemType() {
        String result = "windows";
        if (System.getProperty("os.name").equals("Linux")) {
            result = "linux";
        } else if ("Mac OS X".equals(System.getProperty("os.name"))) {
            result = "Mac OS X";
        }
        return result;
    }

    public static String getWindowsMACAddress() {
        String address = "";
        try {
            ProcessBuilder pb = new ProcessBuilder("ipconfig", "/all");
            Process p = pb.start();
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = br.readLine()) != null) {
                if (line.indexOf("Physical Address") != -1) {
                    int index = line.indexOf(":");
                    address = line.substring(index + 1);
                    break;
                }
            }
            br.close();
            return address.trim();
        } catch (IOException e) {
        }
        return address;
    }

    public static String getLinuxMACAddress() {
        String ip = getLinuxIP();
        String address = getMac(ip);
        return address;
    }

    private static String getMac(String ip) {
        String mac = "";
        if (ip != null) {
            try {
                //                Process process = Runtime.getRuntime().exec("arp " + ip);
                //                Process process = Runtime.getRuntime().exec(cmd);
                //                InputStreamReader ir = new InputStreamReader(process.getInputStream());
                //                LineNumberReader input = new LineNumberReader(ir);
                //                String line;
                //                StringBuffer s = new StringBuffer();
                //                while ((line = input.readLine()) != null) {
                //                    s.append(line);
                //                }
                //                mac = s.toString();
                //                if (StrUtil.isNotNull(mac)) {
                //                    mac = mac.substring(mac.indexOf(":") - 2, mac.lastIndexOf(":") + 3);
                //                }
                InetAddress address = InetAddress.getByName(ip);
                NetworkInterface network = NetworkInterface.getByInetAddress(address);
                if (network != null) {
                    byte[] macs = network.getHardwareAddress();
                    if (macs != null) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < macs.length; i++) {
                            sb.append(String.format("%02X%s", macs[i],
                                    (i < macs.length - 1) ? "-" : ""));
                        }
                        mac = sb.toString();
                    }
                }
            } catch (Exception e) {
            }
        }
        return mac;

    }

    private static String getLinuxIP() {
        String localIp = getIp();
        if (StrUtil.isNotNull(localIp)) {
            return localIp;
        }
        localIp = "127.0.0.1";
        Enumeration<NetworkInterface> netInterfaces = null;
        try {
            netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements()) {
                NetworkInterface ni = netInterfaces.nextElement();
                String name = ni.getName();
                Enumeration<InetAddress> ips = ni.getInetAddresses();
                while (ips.hasMoreElements()) {
                    String Ip = ((InetAddress) ips.nextElement()).getHostAddress();
                    if (!"127.0.0.1".equals(Ip) && linusIp.indexOf(name.toLowerCase()) != -1
                            && Ip.indexOf(":") == -1) {
                        localIp = Ip;
                        break;
                    }
                }
            }
        } catch (Exception e) {
        }
        return localIp;
    }

    private static String getIp() {
        try {
            return getFirstNonLoopbackAddress(true, false).getHostAddress();
        } catch (SocketException e) {
        }
        return "";
    }

    private static InetAddress getFirstNonLoopbackAddress(boolean preferIpv4, boolean preferIPv6)
            throws SocketException {
        Enumeration en = NetworkInterface.getNetworkInterfaces();
        while (en.hasMoreElements()) {
            NetworkInterface i = (NetworkInterface) en.nextElement();
            for (Enumeration en2 = i.getInetAddresses(); en2.hasMoreElements(); ) {
                InetAddress addr = (InetAddress) en2.nextElement();
                if (!addr.isLoopbackAddress()) {
                    if (addr instanceof Inet4Address) {
                        if (preferIPv6) {
                            continue;
                        }
                        return addr;
                    }
                    if (addr instanceof Inet6Address) {
                        if (preferIpv4) {
                            continue;
                        }
                        return addr;
                    }
                }
            }
        }
        return null;
    }

    /**
     * description: 判断字符串是否为空，如果为空取给定的默认值
     *
     * @param text 传入的字符串
     * @param defaultStr 给定的默认值
     */
    public static String getDefaultStr(String text, String defaultStr) {
        if ("".equals(text) || ("null".equalsIgnoreCase(defaultStr)))
            return defaultStr;
        return text;
    }

    public static String getMacAddress() {
        String address = "";
        if (StrUtil.isNull(MAC_ADDR)) {
            String os = getSystemType();
            if (os != null && os.startsWith("windows")) {
                address = getLocalMac();
            } else {
                address = getMac(getLinuxIP());
            }
            MAC_ADDR = address;
        } else {
            address = MAC_ADDR;
        }
        log.debug("Local MAC Address = " + address);
        return address;
    }

    //获取MAC地址的方法
    private static String getLocalMac() {
        try {
            InetAddress ia = InetAddress.getLocalHost();//获取本地IP对象
            //获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
            byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
            //下面代码是把mac地址拼装成String
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < mac.length; i++) {
                if (i != 0) {
                    sb.append("-");
                }
                //mac[i] & 0xFF 是为了把byte转化为正整数
                String s = Integer.toHexString(mac[i] & 0xFF);
                sb.append(s.length() == 1 ? 0 + s : s);
            }
            //把字符串所有小写字母改为大写成为正规的mac地址并返回
            return sb.toString().toUpperCase();
        } catch (Exception e) {
        }
        return "";
    }

}
